/**************************************************************************
*   Copyright (C) 2009 Chernov Dmitry                                     *
*   diman4ik.chernov@gmail.com                                            *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
*   This program is distributed in the hope that it will be useful,       *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU General Public License for more details.                          *
*                                                                         *
*   You should have received a copy of the GNU General Public License     *
*   along with this program; if not, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
***************************************************************************/

#ifndef KORNRES_SCENE
#define KORNERS_SCENE

#include "korners_game_engine.h"
#include "korners_time_line.h"

#include <QGraphicsScene>
#include <QTime>
#include <QTimer>

class KGamePopupItem;
class KornersCapItem;
class KornersEngineThread;


/**
 *  Displays and drives the game
 */
class KornersScene : public QGraphicsScene
{
    Q_OBJECT
public:
    explicit KornersScene( QObject *parent = 0 );
    ~KornersScene();

    /**
     *  Resizes scene
     */
    void resizeScene( int width, int height );
    /**
     *  Starts new game
     */
    void startNetworkGameClient( const QString& net_name, int port, const QString& ip_adress );
    void startNetworkGameServer( const QString& net_name, int port );
    void startNewLocalGame( bool multiplayer );
    /**
     *  Toggles time game
     */
    void toggleOnTime( bool onTime );    
    /**
     *  Reset scene
     */
    void resetScene();

public slots:

    /**
     *  Animate route
     */
    void showMovePath( KornersMove mv );
    /**
     *  Highlight possible routes
     */
    void showPaths( const QVector<QPoint>* moves );
    /**
     *  Opponent name received in network game
     */
    void opponentName( QString );
    /**
     *  Show popup notification from game engine
     */
    void showEngineMess( QString text );
    /**
     *  Your turn
     */
    void canPlay();
    /**
     *  You won or loose
     */
    void youWin();
    void youLost();
    /**
     *  Time game, time has changed
     */
    void newTime( QTime time );

signals:
    /**
     *  Start different game engines
     */
    void startGameEngineAI();
    void startGameEngineTimer();
    void startGameEngineDual();
    void startGameEngineNetwork( const QString& net_name, int port, bool server = false,
                                 const QString& ip_adress = "localhost" );
    /**
     *  Notify about players move
     */
    void playerMadeMove( QPoint , QPoint );
    /**
     *  Get moves available to player
     */
    //void getMovesFromPoint( QPoint );
    void capSelected( QPoint );
    /**
     *  Game over (somebody won or lost)
     */
    void gameOver( QTime );
    /**
     *  New status text to show
     */
    void newStatus1( QString );
    void newStatus2( QString );
    /**
     *  Player made first click
     */
    void started();

    void startTiming();

private slots:
    void moveAnimationFrameChanged(int frame);
    void moveAnimFinished();

private:

    /**
     *  Field coords to pixel coords
     */
    inline QPointF fieldToPix(int xField, int yField) const
    {
        return QPointF( m_playFieldRect.x() + m_playFieldBorderSize + xField*m_cellSize,
                        m_playFieldRect.y() + m_playFieldBorderSize + yField*m_cellSize );
    }
    /**
     *  Pixel coords to field coords
     */
    inline QPoint pixToField( const QPointF& p ) const
    {
        return QPoint(static_cast<int>(( p.x()-m_playFieldRect.x()-m_playFieldBorderSize )/m_cellSize),
                      static_cast<int>(( p.y()-m_playFieldRect.y()-m_playFieldBorderSize )/m_cellSize));
    }

    void putCapsInStartPos();
    
    /**
     *  Event handlers
     */
    virtual void drawBackground( QPainter*, const QRectF& );
    virtual void mousePressEvent( QGraphicsSceneMouseEvent* );
    //virtual void timerEvent( QTimerEvent* event );
    /**
     *  Hide route highlighter
     */
    void unshowPaths();
    /**
     *  Begins move animation
     */
    bool startMoveAnimation(const KornersMove& mv);
    /**
     *  If we selected cap
     */
    bool m_capSelected;
    /**
     *  Player's move
     */
    QPoint point_source;
    QPoint point_destination;
    /**       
     * Area of playfield (with border included - if any exists in theme)
     */
    QRect m_playFieldRect;
    /**
     * Size of a playfield border.
     * Equals 0 if there's no border element in current theme
     */
    int m_playFieldBorderSize;
    /**
     *  Cell size in pixels
     */
    int m_cellSize;
    /**
     * Item to show popup messages to user
     */
    KGamePopupItem* m_popupItem;
    /**
     *  If the game is over
     */   
    bool m_gameOver;
    /**
     *  If you made first mouse click
     */
    bool m_gameStarted;
    /**
     *  If you can select caps
     */
    bool m_canPlay;
    /**
     *  If you play time game
     */
    bool m_timeGame;
    /**
     *  Move animation timeline
     */
    KornersTimeLine m_moveTimeLine;
    /**
     *  List of routes to animate
     */
    QVector<KornersMove> m_pendingMoves;
    /**
     *  Current moving cap
     */
    KornersCapItem* m_curMovingCap;
    /**
     *  Opponents name in network game
     */
    QString m_name;
    /**
     *  Save time here
     */
    QTime m_time;
};

#endif
